import {
  useDebounceFn,
  useMemoizedFn,
  useMount,
  useSafeState,
  useUnmount,
} from "ahooks";
import { useSidebar } from "@shadcn/sidebar";
import events from "@/ui/events";
import { GlobalModel } from "@/ui/context";
import { useContext, useMemo, useRef } from "react";
import type { BrowserSession } from "@common/models";
import { getValueOrDie } from "@common/utils";
import * as rpcXHSApis from "@/ui/utils/rpc/xhs";
import { message } from "antd";
import { syncMention } from "@/ui/utils/rpc/xhs";
// import * as rpcApis from "@/ui/utils/rpc";
// import pLimit from "p-limit";

type ShowMethod = (visible: boolean) => void;

export function useViewModel() {
  const globalModel = getValueOrDie(useContext(GlobalModel));
  const { setOpen } = useSidebar();
  const unhandlers = useRef<Array<() => void>>([]);
  const [isSettingsShow, setIsSettingsShow] = useSafeState(false);

  const listenCollapse = useMemoizedFn(({ collapse }) => {
    setOpen(!collapse);
  });
  const [unreadAmount, setUnreadAmount] = useSafeState<Record<string, number>>(
    {},
  );

  const totalUnreadAmount = useMemo(() => {
    let ans = 0;
    const unreads: Record<string, number> = {};
    for (const r of globalModel.mentions?.records ?? []) {
      if (!r.isChecked) {
        ans += 1;

        if (!unreads[r.currentUserId]) {
          unreads[r.currentUserId] = 1;
        } else {
          unreads[r.currentUserId] += 1;
        }
      }
    }
    setUnreadAmount(unreads);
    return ans;
  }, [globalModel.mentions?.records]);

  const dialogARef = useRef<{ show: ShowMethod }>(null);
  const dialogBRef = useRef<{ show: ShowMethod }>(null);

  const loadMentions = useDebounceFn(
    async () => {
      const res = await rpcXHSApis.loadAllMentions();
      if (globalModel.mentions?.records?.length) {
        globalModel.mentions = {
          hasMore: res.hasMore,
          records: res.records,
        };
      } else {
        globalModel.mentions = res;
      }
    },
    { leading: true, trailing: false },
  );

  const onAccountSelected = (session: BrowserSession) => async () => {
    const model = getValueOrDie(globalModel);
    if (model.currentSession?.id === session.id) return;

    model.currentSession = session;

    globalModel.updating = { [session.id]: true };
    message.success(
      `开始更新【${session.apps.xhs.user?.nickname}】评论数据，请稍侯`,
    );
    try {
      await syncMention({ sessionId: session.id });
      await loadMentions.run();
      message.success(`【${session.apps.xhs.user?.nickname}】评论数据更新完成`);
    } catch (err) {
      const msg = (err as Error)?.message ?? `${err}`;
      console.error("评论数据更新异常", err, session);
      message.error(
        `【${session.apps.xhs.user?.nickname}】评论数据更新异常：${msg}`,
      );
    }
    globalModel.updating = {};
  };
  const onCreateAccountClick = useMemoizedFn(() => {
    dialogARef.current?.show(true);
  });

  const init = useDebounceFn(
    async () => {
      const hasLoginedAccount = !!(globalModel.profiles ?? []).find(
        (r) => !!r.xhsUser,
      );
      if (!hasLoginedAccount) {
        // 没有登录过小红书，引导用户添加账号
        events.XHM.USER.LOGIN.once(onCreateAccountClick);
      } else {
        // todo 自动登录。要考虑登录失败的场景，不能自动登录的会话要先结束掉，避免阻塞其他的会话登录
        // rpcApis.settings.getAll().then(async (config) => {
        //   const autoLogin = config.AUTO_LOGIN;
        //   if (!autoLogin) {
        //     return;
        //   }
        //
        //   const limit = pLimit(config.AUTO_LOGIN_CONCURRENCY);
        //
        //   const tasks = (globalModel.sessions ?? []).map((session) =>
        //     limit(() => onAccountSelected(session)()),
        //   );
        //   await Promise.all(tasks);
        // });

        [
          events.Global.XHS.Mention.Synced.on(() => {
            return loadMentions.run();
          }),
          events.Sidebar.Collapse.Set.on(listenCollapse),
        ].forEach((unhandler) => unhandlers.current.push(unhandler));

        await loadMentions.run();
      }
    },
    { leading: false, trailing: true, wait: 200 },
  );

  useMount(init.run);
  useUnmount(() => {
    unhandlers.current.forEach((action) => action());
  });

  return {
    globalModel,
    totalUnreadAmount,
    unreadAmount,
    isSettingsShow,

    dialogARef,
    dialogBRef,

    setIsSettingsShow,
    onCreateAccountClick,
    onAccountSelected,
  };
}
